package com.lottery.material.util;

import java.util.List;

import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lottery.material.enumeration.ResultEnum;
import lombok.Data;

/**
 * @description 自定义响应结构
 * @author rambo
 * @date 2018年5月23日 上午11:12:51
 */
@Data
@SuppressWarnings("ALL")
public class ResponseResult {

	/**
	 * @description 定义jackson对象
	 */
	private static final ObjectMapper MAPPER = new ObjectMapper();

	/**
	 * @description 响应业务状态
	 */
	@JSONField(ordinal = 1)
	private Integer code;

	/**
	 * @description 响应消息
	 */
	@JSONField(ordinal = 2)
	private String msg;

	/**
	 * @description 响应中的数据
	 */
	@JSONField(ordinal = 3)
	private Object data;

	public ResponseResult() {}

	private ResponseResult(Integer code, String msg, Object data) {
		this.code = code;
		this.msg = msg;
		this.data = data;
	}

	/**
	 * @description 构造函数设置响应业务状态
	 * @param code 响应业务状态
	 * @return
	 */
	public static ResponseResult buildResult(Integer code) {
		return new ResponseResult(code, null, null);
	}

	/**
	 * @description 构造函数只设置响应消息
	 * @param msg 响应消息
	 * @return
	 */
	public static ResponseResult buildResult(String msg) {
		return new ResponseResult(null, msg, null);
	}

	/**
	 * @description 构造函数同时设置响应业务状态和响应消息
	 * @param code 响应业务状态
	 * @param msg 响应消息
	 * @return
	 */
	public static ResponseResult buildResult(Integer code, String msg) {
		return new ResponseResult(code, msg, null);
	}

	/**
	 * @description 构造函数同时设置响应业务状态、响应消息、响应数据
	 * @param code 响应业务状态
	 * @param msg 响应消息
	 * @param data 响应数据
	 * @return
	 */
	public static ResponseResult buildResult(Integer code, String msg, Object data) {
		return new ResponseResult(code, msg, data);
	}

	/**
	 * @description 调用服务成功的统一格式
	 * @param data 响应数据
	 * @return
	 */
	public static ResponseResult buildSuccess(Object data) {
		return new ResponseResult(200, "调用服务接口成功！", data);
	}

	/**
	 * @description 调用服务异常的统一格式
	 * @return
	 */
	public static ResponseResult buildException() {
		return new ResponseResult(500, "调用服务接口异常！", null);
	}

	/**
	 * @description 构造函数同时设置响应业务状态和响应消息（入参是响应信息枚举对象）
	 * @param resultEnum 响应结果信息枚举类
	 * @return
	 */
	public static ResponseResult buildResult(ResultEnum resultEnum) {
		return new ResponseResult(resultEnum.getCode(), resultEnum.getMessage(), null);
	}

    /**
     * @description 构造函数同时设置响应业务状态、响应消息、响应数据
     * @param resultEnum 响应结果信息枚举类
     * @param data 响应数据
     * @return
     */
    public static ResponseResult buildResult(ResultEnum resultEnum, Object data) {
		return new ResponseResult(resultEnum.getCode(), resultEnum.getMessage(), data);
	}

	/**
	 * @description 构造函数同时设置响应业务状态、制定字符串格式响应消息
	 * @param resultEnum 响应结果信息枚举类
	 * @param datas 生成格式化的字符串
	 * @return
	 */
	public static ResponseResult buildFormatResult(ResultEnum resultEnum, Object... datas) {
		return new ResponseResult(resultEnum.getCode(), String.format(resultEnum.getMessage(), datas), null);
	}

	/**
	 * 说明：data为null直接将json字符串转pojo对象
	 * @description ResponseResult的json字符串转ResponseResult对象
	 * @param json
	 * @return
	 */
	public static ResponseResult format(String json) {
		try {
			// json字符串中data为null，将json字符串转换成ResponseResult对象
			return MAPPER.readValue(json, ResponseResult.class);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 说明：data为json字符串转pojo对象
	 * @description ResponseResult的json字符串转ResponseResult对象
	 * @param json json数据
	 * @param clazz ResponseResult中的object类型
	 * @return
	 */
	public static ResponseResult formatToPojo(String json, Class<?> clazz) {
		try {
			if (clazz == null) {
				// 如果json字符串中data为null，将json字符串转换成ResponseResult对象
				return MAPPER.readValue(json, ResponseResult.class);
			}
			JsonNode jsonNode = MAPPER.readTree(json);
			// 获取data的值
			JsonNode data = jsonNode.get("data");
			// obj用来存储data
			Object obj = null;
			if (data.isObject()) {// 如果data是一个pojo对象
				obj = MAPPER.readValue(data.traverse(), clazz);
			} else if (data.isTextual()) {// 如果data是一个纯字符串
				obj = MAPPER.readValue(data.asText(), clazz);
			}
			// 将ResponseResult的json字符串格式转换成ResponseResult对象
			return buildResult(jsonNode.get("code").intValue(), jsonNode.get("msg").asText(), obj);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 说明：data为json字符串转pojo的集合对象
	 * @description ResponseResult的json字符串转ResponseResult对象
	 * @param json json数据
	 * @param clazz 集合中的类型
	 * @return
	 */
	public static ResponseResult formatToList(String json, Class<?> clazz) {
		try {
			if (clazz == null) {
				// 如果json字符串中data为null，将json字符串转换成ResponseResult对象
				return MAPPER.readValue(json, ResponseResult.class);
			}
			JsonNode jsonNode = MAPPER.readTree(json);
			// 获取data的值
			JsonNode data = jsonNode.get("data");
			// obj用来存储data
			Object obj = null;
			if (data.isArray() && data.size() > 0) {// 如果data是数组格式并且长度不为0
				obj = MAPPER.readValue(data.traverse(), MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
			}
			// 将ResponseResult的json字符串格式转换成ResponseResult对象
			return buildResult(jsonNode.get("code").intValue(), jsonNode.get("msg").asText(), obj);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

}
